home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1989, 1990, 1991, 1992, John F. Haugh II
- * All rights reserved.
- *
- * Permission is granted to copy and create derivative works for any
- * non-commercial purpose, provided this copyright notice is preserved
- * in all copies of source code, or included in human readable form
- * and conspicuously displayed on all copies of object code or
- * distribution media.
- */
-
- #include <ctype.h>
- #ifndef BSD
- #include <string.h>
- #include <memory.h>
- #else
- #include <strings.h>
- #define strchr index
- #define strrchr rindex
- #endif
- #include "config.h"
-
- #ifndef lint
- static char sccsid[] = "@(#)obscure.c 3.6 20:37:32 3/7/92";
- #endif
-
- extern int getdef_bool();
- extern int getdef_num();
-
- #ifdef NEED_STRSTR
- /*
- * strstr - find substring in string
- */
-
- char *
- strstr (string, pattern)
- char *string;
- char *pattern;
- {
- char *cp;
- int len;
-
- len = strlen (pattern);
-
- for (cp = string;cp = strchr (cp, *pattern);) {
- if (strncmp (cp, pattern, len) == 0)
- return cp;
-
- cp++;
- }
- return 0;
- }
- #endif
-
- /*
- * Obscure - see if password is obscure enough.
- *
- * The programmer is encouraged to add as much complexity to this
- * routine as desired. Included are some of my favorite ways to
- * check passwords.
- */
-
- /*ARGSUSED*/
- int obscure (old, new)
- char *old;
- char *new;
- {
- int i;
- char oldmono[32];
- char newmono[32];
- char wrapped[64];
-
- if (old[0] == '\0')
- return (1);
-
- if ( strlen(new) < getdef_num("PASS_MIN_LEN", 0) ) {
- printf ("Too short. ");
- return (0);
- }
-
- /*
- * Remaining checks are optional.
- */
- if ( !getdef_bool("OBSCURE_CHECKS_ENAB") )
- return (1);
-
- for (i = 0;new[i];i++)
- newmono[i] = tolower (new[i]);
-
- for (i = 0;old[i];i++)
- oldmono[i] = tolower (old[i]);
-
- if (strcmp (new, old) == 0) { /* the same */
- printf ("No Change. ");
- return (0);
- }
- if (palindrome (newmono, oldmono)) /* a palindrome */
- return (0);
-
- if (strcmp (newmono, oldmono) == 0) { /* case shifted */
- printf ("Case changes only. ");
- return (0);
- }
- if (similiar (newmono, oldmono)) /* jumbled version */
- return (0);
-
- if (simple (old, new)) /* keyspace size */
- return (0);
-
- strcpy (wrapped, oldmono);
- strcat (wrapped, oldmono);
- if (strstr (wrapped, newmono)) {
- printf ("Rotated. ");
- return (0);
- }
- return (1);
- }
-
- /*
- * can't be a palindrome - like `R A D A R' or `M A D A M'
- */
-
- /*ARGSUSED*/
- int palindrome (old, new)
- char *old;
- char *new;
- {
- int i, j;
-
- i = strlen (new);
-
- for (j = 0;j < i;j++)
- if (new[i - j - 1] != new[j])
- return (0);
-
- printf ("A palindrome. ");
- return (1);
- }
-
- /*
- * more than half of the characters are different ones.
- */
-
- /*ARGSUSED*/
- int similiar (old, new)
- char *old;
- char *new;
- {
- int i, j;
- char *strchr ();
-
- for (i = j = 0;new[i] && old[i];i++)
- if (strchr (new, tolower (old[i])))
- j++;
-
- if (i >= j * 2)
- return (0);
-
- printf ("Too similiar. ");
- return (1);
- }
-
- /*
- * a nice mix of characters.
- */
-
- /*ARGSUSED*/
- int simple (old, new)
- char *old;
- char *new;
- {
- int digits = 0;
- int uppers = 0;
- int lowers = 0;
- int others = 0;
- int size;
- int i;
-
- for (i = 0;new[i];i++) {
- if (isdigit (new[i]))
- digits++;
- else if (isupper (new[i]))
- uppers++;
- else if (islower (new[i]))
- lowers++;
- else
- others++;
- }
-
- /*
- * The scam is this - a password of only one character type
- * must be 8 letters long. Two types, 7, and so on.
- */
-
- size = 9;
- if (digits) size--;
- if (uppers) size--;
- if (lowers) size--;
- if (others) size--;
-
- if (size <= i)
- return 0;
-
- printf ("Too Simple. Use a longer password, or a mix of upper\n");
- printf ("and lower case letters and numerics. ");
- return 1;
- }
-